export const createWebSocket = <T>(url: string, dataHandler: (arg: T) => void): WebSocket => {
    const ws = new WebSocket(url);

    // 当连接打开时执行
    ws.onopen = function () {
        console.log("WebSocket 连接已打开");
        // 向服务器发送一个消息
        // ws.send("你好，服务器！");
    };

    // 当接收到服务器消息时执行
    ws.onmessage = function (event) {
        // console.log("收到服务器消息: " + event.data);
        const data = event.data
        dataHandler(JSON.parse(data))
    };

    // 当连接关闭时执行
    ws.onclose = function () {
        console.log("WebSocket 连接已关闭");
        // ws.
    };

    // 当连接出错时执行
    ws.onerror = function (error) {
        console.error("WebSocket 发生错误: ", error);
    };
    return ws
}
export interface ReconnectableWebsocket {
    ws: WebSocket | null,
    close: () => void,
    send: (data: string) => void,
    registerHandler: (type: string, handler: (msg: any) => void) => void
    registeredHandlers: { [key: string]: { type: string, handler: (msg: any) => void } }
}

export function createReconnectableWebSocket<T>(url: string, dataHandler: (arg: T) => void): ReconnectableWebsocket {
    // let ws: WebSocket | null = null;
    let isClosedByUser = false;
    let reconnectInterval = 5000; // 5 seconds
    const states: ReconnectableWebsocket = {
        ws: null as WebSocket | null,
        registeredHandlers: {},
        close: () => {
            isClosedByUser = true;
            if (states.ws) {
                states.ws.close();
            }
        },
        registerHandler: (type: string, handler: (msg: any) => void) => {
            states.registeredHandlers[type] = { type, handler };
        },
        send: (data: string) => {
            if (states.ws) {
                states.ws.send(data)
            } else {
                console.error('WebSocket is not connected');
            }
        }
    }

    function connect() {
        states.ws = new WebSocket(url);

        states.ws.onopen = () => {
            console.log('WebSocket connection established');
            isClosedByUser = false;
        };

        states.ws.onmessage = (event) => {
            console.log('Message from server:', event.data);
            const data = event.data
            dataHandler(JSON.parse(data))
        };

        states.ws.onerror = (error) => {
            console.error('WebSocket error:', error);
        };

        states.ws.onclose = () => {
            console.log('WebSocket connection closed');
            if (!isClosedByUser) {
                setTimeout(connect, reconnectInterval);
            }
        };
    }
    setTimeout(connect, 50);
    return states;
}

// 创建根据消息类型（type字段）派发消息的websocket
// msgInList: 消息是否在一个列表中，默认为False.如果为True,则逐项去除并且进行处理。
export function createMultiTypedReconnectableWebSocket(url: string, options?: { msgTypeAttrName?: string, msgInList?: boolean }): ReconnectableWebsocket {
    if (!options) {
        options = {}
    }
    const msgTypeAttrName = options.msgTypeAttrName || 'type'
    const msgInList = options.msgInList || false
    const parseSingleMsg = (msg: any) => {
        const type = msg[msgTypeAttrName]
        const handler = states.registeredHandlers[type]
        if (handler) {
            handler.handler(msg)
        } else {
            console.error(`No handler found for message type: ${type}`)
        }
    }
    const parseListedMsg = (msg: any[]) => {
        for (const item of msg) {
            parseSingleMsg(item)
        }
    }
    const parser = msgInList ? parseListedMsg : parseSingleMsg
    const states = createReconnectableWebSocket<any>(url, (msg: any[]) => {
        parser(msg)
    })
    return states
}